#include "triangle.h"

Triangle::Triangle(d_Vec3f aa, d_Vec3f bb, d_Vec3f cc, Material *m)
{
	a = aa;
	b = bb;
	c = cc;
	normal = norm(cross(b-a,c-a));
	material = m;
	isTextured = false;
}

Triangle::Triangle(d_Vec3f aa, d_Vec3f bb, d_Vec3f cc, Material *m, d_Vec2f t0, d_Vec2f t1, d_Vec2f t2, char *texfilename)
{
	a = aa;
	b = bb;
	c = cc;
	ta = t0;
	tb = t1;
	tc = t2;
	normal = norm(cross(b-a,c-a));
	material = m;
	texture = texture->LoadTGA(texfilename);
	width = texture->Width();
	height = texture->Height();
	isTextured = true;
}

d_Vec2f project(d_Vec3f vec, int coord)
{
	switch(coord)
	{
	case 0:
		return d_Vec2f(vec[1],vec[2]);
	case 1:
		return d_Vec2f(vec[0],vec[2]);
	case 2:
		return d_Vec2f(vec[0],vec[1]);
	}
}

bool Triangle::intersect(const Ray &r, Hit &h, float tmin)
{
/*
	d_Vec3f dir = r.getDirection();
	d_Vec3f ori = r.getOrigin();
	
	float dist = - dot(ori-a,normal)/dot(dir,normal);
	if(dist<0)
		return false;
		
	d_Vec3f inter = ori + dir*dist;
	
	float tmp = -100000;
	int maxcoord;
	for(int i=0; i<3; i++)
		if(normal[i]>tmp)
		{
			tmp = normal[i];
			maxcoord = i;
		}
	d_Vec2f nb = project(b,maxcoord)-project(a,maxcoord);
	d_Vec2f nc = project(c,maxcoord)-project(a,maxcoord);	
	d_Vec2f np = project(inter,maxcoord);
	
	float u = (np[1]*nc[0]-np[0]*nc[1])/(nb[1]*nc[0]-nb[0]*nc[1]);
	float v = (np[1]*nb[0]-np[0]*nb[1])/(nc[1]*nb[0]-nc[0]*nb[1]);
	
	if(u>=0&&v>=0&&u+v<=1)
	{
		h.set(dist,material,normal);
		return true;
	}
	return false;
*/

	d_Vec3f ap = b-a;
	d_Vec3f bp = c-a;
	d_Vec2f at = tb-ta;
	d_Vec2f bt = tc-ta;
	d_Vec3f dir = r.getDirection();
	d_Mat3f solution(ap[0], bp[0], -dir[0],
			 		 ap[1], bp[1], -dir[1],
			 		 ap[2], bp[2], -dir[2]);

	d_Vec3f sol = inv(solution)*(r.getOrigin()-a);

	if(sol[0]>=0 && sol[1]>=0 && sol[0]+sol[1]<=1 && sol[2]<h.getT() && sol[2]>tmin)
	{
		if(isTextured)
		{
		    cout << "textured" << endl;
			d_Vec2f posit = ta + at*sol[0]+bt*sol[1];
			//posit[1] = 1-posit[1];
			//cout << (int)(posit[0]*256) << endl;
			d_Vec3f color = texture->GetPixel((int)floor(posit[0]*255),(int)floor(posit[1]*255));
			if(sol[2]<h.getT())
				h.set(sol[2],new PhongMaterial(color,d_Vec3f(0,0,0),1,d_Vec3f(0,0,0),d_Vec3f(0,0,0),0,NULL, NULL, NULL) , normal);
		}
		else
			h.set(sol[2], material, normal);
		return true;
	}
	//return true;
	return false;

}


